package org.simp.interceptor;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.simp.annotation.SimpControllerManager;
import org.simp.core.body.SimpBody;
import org.simp.core.body.decoder.SimpBodyDecoder;
import org.simp.core.head.SimpHeader;
import org.simp.core.message.SimpMessage;
import org.simp.core.request.SimpRequest;
import org.simp.exception.SimpNotFoundException;
import org.simp.handler.SimpHandler;

/**
 * @author zhuhaitao at 2014-5-26
 *
 * 
 */
public abstract class AbstractHandlerInterceptor implements SimpHandlerInterceptor{
	
	protected SimpBodyDecoder decoder;
	
	protected SimpControllerManager manager;

	public AbstractHandlerInterceptor( SimpBodyDecoder decoder ,SimpControllerManager manager){
		this.decoder = decoder;
		this.manager = manager;
	}
	@Override
	public void receiveRequest(SimpRequest request, SimpHandler handler) {

		/**如果有消息体，对消息体进行解码**/
		if(request.hasBody()){
			try {
				/**如果有消息体，当前临时消息体是RouteBody，一个byte数组**/
				SimpBody body = decoder.decoder(request.getHead(), request.getBody().encode());
				request.setBody(body);
			} catch (SimpNotFoundException e) {
				e.printStackTrace();
			}
		}
		if(!preHandler(request, handler)){
			return;
		}
		SimpMessage message = null;

		Object controller = manager.getController(request.getHead().getRequestId());
		Method method = manager.getMethod(request.getHead().getRequestId());
		if(controller != null && method != null){
			Class<?>[] clazzes = method.getParameterTypes();
			Object[] params = new Object[clazzes.length];
			for(int i=0;i<clazzes.length;i++){
				Class<?> clazz = clazzes[i];
				if(clazz.isAssignableFrom(SimpHandler.class)){
					params[i] = handler;
				}else if(clazz.isAssignableFrom(SimpRequest.class)){
					params[i] = request;
				}else if(request.hasBody() && clazz.isInstance(request.getBody())){
					params[i] = request.getBody();
				}else if(clazz.isAssignableFrom(SimpHeader.class)){
					params[i] = request.getHead();
				}else {
					params[i] = null;
				}
			}
			try {
				Object response = method.invoke(controller, params);
				if(response instanceof SimpMessage){
					 message = (SimpMessage) response;
				}
			} catch (IllegalArgumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}else {
			throwSimpRequest(request, handler);
			return;
		}
		postHandler(request, message, handler);

	
		
	}


}
